package com.atguigu.gmall.payment.controller;

import com.alipay.api.internal.util.AlipaySignature;
import com.atguigu.gmall.common.result.Result;
import com.atguigu.gmall.model.enums.PaymentType;
import com.atguigu.gmall.model.payment.PaymentInfo;
import com.atguigu.gmall.payment.config.AlipayConfig;
import com.atguigu.gmall.payment.service.AlipayService;
import com.atguigu.gmall.payment.service.PaymentService;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Controller
@RequestMapping("/api/payment/alipay")
public class PaymentApiController {

    @Autowired
    private AlipayService alipayService;

    @Autowired
    private PaymentService paymentService;
    @Autowired
    private RedisTemplate redisTemplate;



    /**
     * http://localhost:8205/api/payment/alipay/closePay/25
     * 关闭支付宝记录
     * @param orderId
     * @return
     */
    @GetMapping("/closePay/{orderId}")
    @ResponseBody
    public boolean closePay(@PathVariable Long orderId){


        return alipayService.closePay(orderId);
    }

    /**
     * http://localhost:8205/api/payment/alipay/checkPayment/30
     * 查询支付宝交易记录
     * @param orderId
     * @return
     */
    @GetMapping("/checkPayment/{orderId}")
    @ResponseBody
    public boolean checkPayment(@PathVariable Long orderId){


        return alipayService.checkPayment(orderId);
    }


    /**、
     * /api/payment/alipay/getPaymentInfo/{outTradeNo}
     * 获取支付信息
     * @param outTradeNo
     * @return
     */
    @GetMapping("/getPaymentInfo/{outTradeNo}")
    @ResponseBody
    public PaymentInfo getPaymentInfo(@PathVariable String outTradeNo ){


        return paymentService.getPaymentInfo(outTradeNo,PaymentType.ALIPAY.name());

    }

    /**
     * 查看退款结果
     * http://localhost:8205/api/payment/alipay/findrefund/20
     * @param orderId
     * @return
     */
    @GetMapping("/findRefund/{orderId}")
    @ResponseBody
    public Result findRefund(@PathVariable Long orderId){

        return alipayService.findRefund(orderId);
    }




    /**
     * http://localhost:8205/api/payment/alipay/refund/20
     * 退款
     * @return
     */
    @GetMapping("/refund/{orderId}")
    @ResponseBody
    public Result refund(@PathVariable Long orderId){

        return alipayService.refund(orderId);
    }

    /**
     * /api/payment/alipay/callback/notify
     * 异步回调
     * @return
     *
     * app_id=2016092101248425&
     * buyer_id=2088102114562585&
     * buyer_pay_amount=0.80&
     * fund_bill_list=[{"amount":"0.80","fundChannel":"ALIPAYACCOUNT"},{"amount":"0.20","fundChannel":"MDISCOUNT"}]&
     * gmt_create=2016-10-12 21:36:12&
     * gmt_payment=2016-10-12 21:37:19&
     * invoice_amount=0.80
     * &notify_id=7676a2e1e4e737cff30015c4b7b55e3kh6&
     * notify_time=2016-10-12 21:41:23&
     * notify_type=trade_status_sync&
     * out_trade_no=mobile_rdm862016-10-12213600&
     * passback_params=passback_params123&
     * point_amount=0.00&receipt_amount=0.80&
     * seller_id=2088201909970555&
     * subject=PC网站支付交易&
     * total_amount=1.00&
     * trade_no=2016101221001004580200203978&
     * trade_status=TRADE_SUCCESS&
     * voucher_detail_list=[{"amount":"0.20","merchantContribute":"0.00","name":"5折券","otherContribute":"0.20","type":"ALIPAY_DISCOUNT_VOUCHER","voucherId":"2016101200073002586200003BQ4"}]
     *
     */
    @PostMapping("/callback/notify")
    @ResponseBody
    @SneakyThrows
    public String callbackNotiry(@RequestParam Map<String ,String> paramsMap){


        //异步验签
        //调用SDK验证签名
        boolean signVerified = AlipaySignature.rsaCheckV1(paramsMap, AlipayConfig.alipay_public_key, AlipayConfig.charset, AlipayConfig.sign_type);

        //获取订单交易号
        String out_trade_no = paramsMap.get("out_trade_no");
        //查询记账信息paymentInfo
        PaymentInfo paymentInfo=paymentService.getPaymentInfo(out_trade_no, PaymentType.ALIPAY.name());
        //获取支付宝返回的总金额
        String total_amount = paramsMap.get("total_amount");
        //获取支付宝APPiD
        String app_id = paramsMap.get("app_id");
        //获取支付宝订单状态
        String status = paramsMap.get("trade_status");

        if(signVerified){
            // TODO 验签成功后，按照支付结果异步通知中的描述，
            //  对支付结果中的业务内容进行二次校验，
            //  校验成功后在response中返回success并继续商户自身业务处理，校验失败返回failure
            if(paymentInfo!=null &&
                    new BigDecimal("0.01").compareTo(new BigDecimal(total_amount))==0&&
                    AlipayConfig.app_id.equals(app_id)){

                //判断
                if("TRADE_SUCCESS".equals(status)||"TRADE_FINISHED".equals(status)){


                    //获取notify_id
                    String notifyId = paramsMap.get("notify_id");
                    //判断是否重复消费
                    Boolean result = redisTemplate.opsForValue().setIfAbsent(notifyId, notifyId, 1464, TimeUnit.MINUTES);
                    //判断
                    if(!result){

                        return "success";
                    }

                    //修改记账信息状态
                    paymentService.updatePaymentStatus(out_trade_no,PaymentType.ALIPAY.name(),paramsMap);



                    return "success";

                }

            }



        }else{
            // TODO 验签失败则记录异常日志，并在response中返回failure.
            return "failure";
        }


        return "failure";
    }

    /**
     * 同步回调
     *  /api/payment/alipay/callback/return
     * @return
     */
    @GetMapping("/callback/return")
    public String callbackReturn(){


        return "redirect:"+ AlipayConfig.return_order_url;
    }

    /**
     * 支付宝预下单
     * @param orderId
     * @return
     */
    @GetMapping("/submit/{orderId}")
    @ResponseBody
    public String submit(@PathVariable Long orderId){

        String from =alipayService.createAlipay(orderId);

        return  from;
    }
}
